﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using Estimate.Common.DBFieldTypes;
using Estimate.Common.Repository;
using Estimate.Common.Entity;
using Estimate.Common.Estimate;
using Estimate.Common.Estimate.EstimateValue;
using Newtonsoft.Json;

namespace Estimate.Reports
{
    /// <summary>
    /// 预报员排名报表类
    /// </summary>
    public class ForecasterRankReport
    {
        #region 变量与对象
        private FullInfoReport memberReportScore;// 得分对象
        private List<string> Forecasters=new List<string>();//所有预报员
        //private List<string> NeedRemoveTables = new List<string>() { "_SiteFore", "Jiangsu_SiteFore", "Schedule_SiteFore", "St_SiteFore" };
        protected string _connectionString;
        ExecutionStatus exeStatus;//程序执行状态
        ForecasterRankResult Result = new ForecasterRankResult();//排名结果对象
        int TotalMonths = 0;

        /// <summary>
        /// 空semi存放路径
        /// </summary>
        public string EmptySemisDirectory="";
        #endregion

        #region 构造函数
        /// <summary>
        /// 预报员排名类构造函数，默认所有省台预报员参与排名
        /// </summary>
        /// <param name="connectionString">数据库连接字符串</param>
        /// <param name="tid">程序执行任务号</param>
        public ForecasterRankReport(string connectionString, string tid)
        {
            _connectionString = connectionString;

            if (tid != "") exeStatus = new ExecutionStatus(tid);
            if (exeStatus != null) exeStatus.SetMessage("Initial", "正在准备...");

            Initial();

            if (exeStatus != null) exeStatus.DeleteMessage("Initial");
        }

        /// <summary>
        /// 预报员排名类构造函数，指定省台预报员参与排名
        /// </summary>
        /// <param name="forecasters">省台预报员集合字符串,格式为:'yujw','zhongps',......</param>
        /// <param name="connectionString"></param>
        /// <param name="tid"></param>
        public ForecasterRankReport(string[] forecasters, string connectionString, string tid)
        {
            _connectionString = connectionString;

            if (tid != "") exeStatus = new ExecutionStatus(tid);
            if (exeStatus != null) exeStatus.SetMessage("Initial", "正在准备...");

            foreach (string forecaster in forecasters)
                Forecasters.Add(forecaster.Replace("'", ""));

            memberReportScore = new FullInfoReport(_connectionString);
            memberReportScore.CulculateWeatherScore = true;
            memberReportScore.CulculateWaterfallLevelWaterScore = true;
            memberReportScore.CulculateWaterfallAmountWaterScore = true;
            memberReportScore.CulculateMaxTempScore = true;
            memberReportScore.CulculateMinTempScore = true;
            memberReportScore.ExeStatus = exeStatus;

            if (exeStatus != null) exeStatus.DeleteMessage("Initial");

        }

        #endregion

        #region 初始化,检索所有预报员数据表名
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="beginDate"></param>
        /// <param name="endDate"></param>
        /// <param name="clocks"></param>
        /// <param name="sendpoints"></param>
        protected void Initial()
        {
            //所有预报员数据表名
            List<string> ForecasterTables = SiteForeRepository.GetForecasterTables(_connectionString);
            foreach (string table in ForecasterTables)
            {
                if (!table.Contains("_UFore"))
                    continue;
                Forecasters.Add( table.Substring(0, table.IndexOf('_')));
            }
            memberReportScore = new FullInfoReport(_connectionString);
            memberReportScore.CulculateWeatherScore = true;
            memberReportScore.CulculateWaterfallLevelWaterScore = true;
            memberReportScore.CulculateWaterfallAmountWaterScore = true;
            memberReportScore.CulculateMaxTempScore = true;
            memberReportScore.CulculateMinTempScore = true;
            memberReportScore.ExeStatus = exeStatus;
        }
        #endregion

        #region  数据准备并计算
        public  void PrepareData(DateTime beginDate, DateTime endDate, ForeSemiType semitype)
        {
            ForeSpanType[] spans = new ForeSpanType[] { ForeSpanType.FD00_24, ForeSpanType.FD24_48 };
            ForeSendpointType[] sendpoints = new ForeSendpointType[] { ForeSendpointType.H06, ForeSendpointType.H16 };
            PrepareData(beginDate, endDate, spans, sendpoints, semitype);
        }

        public  void PrepareData(DateTime beginDate, DateTime endDate, ForeSpanType[] spans, ForeSendpointType[] sendpoints, ForeSemiType semitype)
        {
            TotalMonths = endDate.Month - beginDate.Month + 1;
            
            if (exeStatus != null)
            {
                exeStatus.TotalSteps = Forecasters.Count * memberReportScore.GetExeStatusTotalSteps(beginDate, endDate, semitype, spans, spans);
                exeStatus.SetMessage("memberReportScore", "运行中");
            }

            try
            {
                List<Dictionary<string, object>> STForecasterScoreList = new List<Dictionary<string, object>>();//排名结果

                foreach (string forecastername in Forecasters)
                {
                   
                    if (exeStatus != null) exeStatus.SetMessage(forecastername, "预报员:" + forecastername);

                    memberReportScore.DataProvider = ForeRepositoryFactory.ForecasterRepository(_connectionString, forecastername);
                    memberReportScore.PrepareData(beginDate, endDate, semitype, spans, spans, sendpoints);

                    Dictionary<string, object> forecasterScore = new Dictionary<string, object>();
                    forecasterScore.Add("user", forecastername);
                    forecasterScore.Add("position", 0);
   
                    foreach (ForeSpanType span in spans)
                    {
                        string[] strs=span.ToString().Split('_');
                        string key = strs[1];
                        forecasterScore.Add(key + "PC", float.Parse(String.Format("{0:N2}", memberReportScore.WaterfallAmountWaterScore[""][span].PC)));
                        forecasterScore.Add(key + "Maxt", float.Parse(String.Format("{0:N2}", memberReportScore.MaxTempScore[""][span].Tt2)));
                        forecasterScore.Add(key + "Mint", float.Parse(String.Format("{0:N2}", memberReportScore.MinTempScore[""][span].Tt2)));
                        forecasterScore.Add(key + "Normal", float.Parse(String.Format("{0:N2}", memberReportScore.WaterfallLevelWaterScore[""][WaterfallLevel.Normal][span].TS)));
                   
                    }
                    forecasterScore.Add("Composite", float.Parse(String.Format("{0:N2}", memberReportScore.CalIndividualShortCompositeScore(""))));
                    forecasterScore.Add("RecordCount", memberReportScore.GetTotalRecordCount(""));
                    forecasterScore.Add("EveryMonthRecordCount", memberReportScore.GetEveryMonthRecordCount(""));
                    forecasterScore.Add("times", 0);//样本数大于20的月数

                    STForecasterScoreList.Add(forecasterScore);

                    if (exeStatus != null) exeStatus.DeleteMessage(forecastername);
                }

                Result.result["data"] = STForecasterScoreList;

                //if (EmptySemisDirectory != "" && memberReportScore.EmptySemis.Count>0)
                //{
                //    string fullfilename = DateTime.Now.ToString("yyyy-MM-dd ") + " " + DateTime.Now.Hour.ToString() + "_" + DateTime.Now.Minute.ToString() + " " + DateTime.Now.Second.ToString();
                //    fullfilename = EmptySemisDirectory + @"\省台预报员排名[空SEMI](" + fullfilename + ").xml";
                    
                //    SaveEmptySemisToXML.Save(beginDate, endDate, semitype, spans, spans, sendpoints, memberReportScore.EmptySemis, fullfilename);
                //}

            }
            catch(Exception ex)
            {
                Result.success = false.ToString();
                Result.msg = ex.ToString();
                if (exeStatus != null)
                    exeStatus.SetMessage("Error", "程序执行出错");
            }

            if (exeStatus != null) exeStatus.DeleteMessage("memberReportScore");
        }
        #endregion

        #region 获取预报员得分排名
        /// <summary>
        /// 获取预报员得分排名
        /// </summary>
        /// <returns></returns>
        public string GetReportDataString()
        {

            try
            {
                if (exeStatus != null) exeStatus.SetMessage("GetForecastRankResult", "获取计算结果");

                int first_end = 0, second_end = 0;
                SortResult((List<Dictionary<string, object>>)Result.result["data"], ref first_end, ref second_end);

                Result.result["first_end"]=first_end;
                Result.result["second_end"] = second_end;

                if (exeStatus != null)
                {
                    exeStatus.DeleteMessage("GetForecastRankResult");
                    exeStatus.SetMessage(true, "ExecutionEnd", "执行完毕");
                    
                }


                return JsonConvert.SerializeObject(Result);

            }
            catch (Exception ex)
            {
                Result.success = false.ToString();
                Result.msg = ex.Message;
                if (exeStatus != null)
                {
                    exeStatus.DeleteMessage("GetForecastRankResult");
                    exeStatus.SetMessage("Error", "执行出错");
                }
                return JsonConvert.SerializeObject(Result);
            }

            

        }
        #endregion

        #region 按照综合分对预报员得分进行排名
        /// <summary>
        /// 按照综合分对省台预报员得分进行排名
        /// </summary>
        /// <param name="STForecasterScoreList"></param>
        /// <param name="FistEnd"></param>
        /// <param name="SecondEnd"></param>
        private void SortResult(List<Dictionary<string, object>> STForecasterScoreList, ref int FistEnd, ref int SecondEnd)
        {
            List<Dictionary<string, object>> frontList = new List<Dictionary<string, object>>();
            List<Dictionary<string, object>> lastList = new List<Dictionary<string, object>>();
            List<Dictionary<string, object>> zeroList = new List<Dictionary<string, object>>();

            int Scale = int.Parse(String.Format("{0:N0}", TotalMonths * 0.8));

            foreach (Dictionary<string, object> Score in STForecasterScoreList)
            {
                if ((int)Score["RecordCount"] == 0)
                    zeroList.Add(Score);
                else
                {
                    int MoreThan20=RecordCountScale((Dictionary<string, int>)Score["EveryMonthRecordCount"]);
                    //样本数大于20的月份的比例>=0.8,则靠前排
                    if (MoreThan20 >= Scale)
                        frontList.Add(Score);
                    else
                        lastList.Add(Score);

                    Score["times"] = MoreThan20;
                }

            }

            STForecasterScoreList.Clear();

            frontList.Sort(new ForecasterCompositeScore("Composite"));
            for (int i = 1; i <= frontList.Count; i++)
            {
                frontList[i - 1]["position"] = i;
                frontList[i - 1].Remove("EveryMonthRecordCount");
                STForecasterScoreList.Add(frontList[i-1]);
            }

            lastList.Sort(new ForecasterCompositeScore("Composite"));
            for (int i = 1; i <= lastList.Count; i++)
            {
                lastList[i - 1]["position"] = i + frontList.Count;
                lastList[i - 1].Remove("EveryMonthRecordCount");
                STForecasterScoreList.Add(lastList[i-1]);
            }

            for (int i = 0; i < zeroList.Count; i++)
            {
                zeroList[i].Remove("EveryMonthRecordCount");
                STForecasterScoreList.Add(zeroList[i]);
            }

            FistEnd = frontList.Count;
            SecondEnd = frontList.Count + lastList.Count;
        }

        /// <summary>
        /// 计算预报员样本数大于20的月份的比例
        /// </summary>
        /// <param name="EveryMonthRecordCount"></param>
        /// <returns></returns>
        private int RecordCountScale(Dictionary<string, int> EveryMonthRecordCount )
        {
            //int MoreThan20 = 0;//样本数大于20的月数
            //float scale = 0;
            int MoreThan20=0;
            foreach (int recordcount in EveryMonthRecordCount.Values)
            {
                if (recordcount >= 20)
                    MoreThan20++;
            }
            //scale = (float)MoreThan20 
            return MoreThan20;
            //return MoreThan20;
        }
        #endregion
    }

}
